#ifndef _q4_H_
#define _q4_H_


#include "OMath.h"


class q4
{
public:

	void SetAxisAngle(const v3 &vecAxis, float fAngle);

	inline void Set(float x, float y, float z, float w);

	inline void SetIdentity();

	void		SetFromMatrix(const m3& rMatrix);
	void SetFromEulerXYZ(const v3 &vecEuler);
	void SetFromEulerYXZ(const v3 &vecEuler);

	q4	operator * (const q4 &quat) const;		// Quat * Quat
	v3	operator * (const v3 &vec) const;			// Quat * Vec
	bool		operator == (const q4 &quat) const;	// Quat == Quat

  m3	CreateMatrix() const;		// create matrix from quaternion
  m3	CreateMatrixAlt() const;		// create matrix from quaternion

	v3	CreateEuler() const;		// create euler angles from quaternion
	void		AxisAngleGet(				// convert to rotation axis and angle
		v3 *pvecAxis,		// pointer to vector where rotation axis will be stored
		float *pfAngle			// pointer to float where angle will be stored
	) const;

	float		Magnitude() const;		// get magnutide/size of quaternion
	void		Normalize();			// set magnitude to 1.0

	q4	Conjugate() const;		// return conjugate of quaternion
	float		Norm() const;			// return norm of quaternion
	q4	Inverse() const;		// return inverse of quaternion

	q4	Slerp(const q4 &quatTarget, float t) const;	// Quat interpolation

public:
	float x, y, z, w;
};

// inlines
void q4::Set(float fx, float fy, float fz, float fw)
{
	x=fx;
	y=fy;
	z=fz;
	w=fw;
}

void q4::SetIdentity()
{
	Set(0.0f, 0.0f, 0.0f, 1.0f);
}

#endif
